﻿using EPlantApp.SignalR.Models;
using Microsoft.AspNetCore.SignalR;
using System.Collections.Concurrent;

namespace EPlantApp.SignalR
{
    /// <summary>
    /// 设备状态实时通信 Hub
    /// </summary>
    public class DeviceStatusHub : Hub
    {
        // 缓存当前所有设备状态（实际项目可替换为数据库/Redis）
        private static readonly ConcurrentDictionary<string, DeviceRealTimeStatus> _deviceStatusCache = new();

        /// <summary>
        /// 大屏连接时，自动获取所有设备当前状态
        /// </summary>
        public override async Task OnConnectedAsync()
        {
            // 1. 向新连接的客户端推送全量设备状态
            var allDevices = _deviceStatusCache.Values.ToList();
            await Clients.Caller.SendAsync("InitializeDeviceStatus", allDevices);

            // 2. 可选：将客户端加入其关注的车间/生产线分组（需客户端传递参数）
            // 例如：从查询参数获取车间ID，加入对应分组
            var workshopId = Context.GetHttpContext()?.Request.Query["workshopId"].ToString();
            if (!string.IsNullOrEmpty(workshopId))
            {
                await Groups.AddToGroupAsync(Context.ConnectionId, $"Workshop_{workshopId}");
            }

            await base.OnConnectedAsync();
        }

        /// <summary>
        /// 客户端主动查询单个设备的历史状态（可选）
        /// </summary>
        /// <param name="deviceId">设备ID</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>历史状态列表</returns>
        public async Task QueryDeviceHistoryStatus(string deviceId, DateTime startTime, DateTime endTime)
        {
            // 实际项目中从数据库查询历史数据
            var history = new List<DeviceRealTimeStatus>() { new DeviceRealTimeStatus { DeviceId = "1", Name = "1" } }; // 模拟数据
            await Clients.Caller.SendAsync("ReceiveDeviceHistory", deviceId, history);
        }

        /// <summary>
        /// （服务器内部调用）推送单个设备状态变更事件
        /// </summary>
        /// <param name="event">状态变更事件</param>
        public async Task BroadcastDeviceStatusChanged(DeviceStatusChangedEvent @event)
        {
            // 更新缓存
            _deviceStatusCache.AddOrUpdate(@event.DeviceId, @event, (id, old) => @event);

            // 1. 向所有客户端广播状态变更（大屏实时刷新）
            await Clients.All.SendAsync("OnDeviceStatusChanged", @event);

            // 2. 可选：仅向设备所属车间的分组推送（减少不必要的推送）
            await Clients.Group($"Workshop_{@event.Workshop}")
                         .SendAsync("OnWorkshopDeviceStatusChanged", @event);
        }

        /// <summary>
        /// （服务器内部调用）批量推送设备状态（如定时全量同步）
        /// </summary>
        /// <param name="devices">设备状态列表</param>
        public async Task BroadcastBatchDeviceStatus(List<DeviceRealTimeStatus> devices)
        {
            // 更新缓存
            foreach (var device in devices)
            {
                _deviceStatusCache.AddOrUpdate(device.DeviceId, device, (id, old) => device);
            }

            // 向所有客户端推送批量更新
            await Clients.All.SendAsync("OnBatchDeviceStatusUpdated", devices);
        }

        /// <summary>
        /// 客户端断开连接时清理资源
        /// </summary>
        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            // 移除分组关联（如果有）
            var workshopId = Context.GetHttpContext()?.Request.Query["workshopId"].ToString();
            if (!string.IsNullOrEmpty(workshopId))
            {
                await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"Workshop_{workshopId}");
            }

            await base.OnDisconnectedAsync(exception);
        }
    }
}
